﻿using FrameworkCore.Models;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;

namespace FrameworkCore.Exceptions;

public class ExceptionHandler : IExceptionHandler
{
    public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
    {
        var result = await Result.SucceedAsync();

        if (exception is ForbiddenAccessException)
        {
            result.Success = false;
            result.Code = StatusCodes.Status403Forbidden;
            result.Message = exception.Message;

            httpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
            await httpContext.Response
                .WriteAsJsonAsync(result, cancellationToken);
        }
        else if (exception is NotFoundException)
        {
            result.Success = false;
            result.Code = StatusCodes.Status404NotFound;
            result.Message = exception.Message;

            httpContext.Response.StatusCode = StatusCodes.Status404NotFound;
            await httpContext.Response
                .WriteAsJsonAsync(result, cancellationToken);
        }
        else if (exception is ServerException)
        {
            result.Success = false;
            result.Code = StatusCodes.Status500InternalServerError;
            result.Message = exception.Message;

            httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
            await httpContext.Response
                .WriteAsJsonAsync(result, cancellationToken);
        }
        else if (exception is UnauthorizedException)
        {
            result.Success = false;
            result.Code = StatusCodes.Status401Unauthorized;
            result.Message = exception.Message;

            httpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
            await httpContext.Response
                .WriteAsJsonAsync(result, cancellationToken);
        }
        else if (exception is FluentValidation.ValidationException)
        {
            result.Success = false;
            result.Code = StatusCodes.Status400BadRequest;
            result.Message = $"参数错误：{exception.Message}";

            httpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
            await httpContext.Response
                .WriteAsJsonAsync(result, cancellationToken);
        }
        else
        {
            result.Success = false;
            result.Code = StatusCodes.Status500InternalServerError;
            result.Message = "服务器错误：未知的异常";

            httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
            await httpContext.Response
                .WriteAsJsonAsync(result, cancellationToken);
        }

        return true;
    }
}
